package com.triones.framework.common.wxpay;

import cn.hutool.core.io.FileUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.WechatPayUploadHttpPost;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager;
import com.wechat.pay.contrib.apache.httpclient.exception.HttpCodeException;
import com.wechat.pay.contrib.apache.httpclient.exception.NotFoundException;
import com.wechat.pay.contrib.apache.httpclient.util.AesUtil;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.springframework.core.io.ClassPathResource;

import javax.annotation.Resource;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.servlet.http.HttpServletRequest;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.cert.X509Certificate;
import java.text.ParseException;
import java.util.*;

@Slf4j
public class WechatPay {
    /**
     * 小程序等appid
     */
    private static final String appId = "wx550382b39834c2f9";
    /**
     * 服务商商户号
     */
    private static final String merchantId = "1684294590";
    /**
     * 商户API证书的证书序列号
     */
    private static final String merchantSerialNumber = "151CDBAD6A6361D7EA83FB2A96389A595BD698EB";
    /**
     * apiv3密钥
     */
    private static final String apiV3Key = "2615b9d566e1c98ac91db38ffeb5d527";
    /**
     * 商户API私钥，如何加载商户API私钥请看 常见问题。 @link: https://github.com/wechatpay-apiv3/wechatpay-apache-httpclient#%E5%A6%82%E4%BD%95%E5%8A%A0%E8%BD%BD%E5%95%86%E6%88%B7%E7%A7%81%E9%92%A5
     */
    private static PrivateKey merchantPrivateKey = null;
    static {
        try {
            merchantPrivateKey = PemUtil.loadPrivateKey(
                new ClassPathResource("apiclient_key.pem").getInputStream());
            String format = merchantPrivateKey.getFormat();
            System.out.println(format);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * 微信支付平台证书列表.
     */
    private static List<X509Certificate> wechatPayCertificates = new ArrayList<>();
    static {
        try {
            wechatPayCertificates.add(PemUtil.loadCertificate(new ClassPathResource("cert.pem").getInputStream()));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws Exception {
        //交易账单
        // getZdUrl("2023-06-07");
        //分账账单
        // getZdUrlFz("2023-06-07");
        getptcert();
    }


    /**
     * jsapi支付（小程序普通商户支付）
     * @param
     * @param
     * @param
     * @return
     */
//    public static JSONObject pay(String orderNum, BigDecimal amount, String openId) throws Exception {
//        //获取金额单位为分
//        BigDecimal totalMoney = amount.multiply(new BigDecimal(100));
//        final CloseableHttpClient httpClient = getHttpClient();
//        HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi");
//        httpPost.addHeader("Accept", "application/json");
//        httpPost.addHeader("Content-type","application/json; charset=utf-8");
//        ByteArrayOutputStream bos = new ByteArrayOutputStream();
//
//        ObjectMapper objectMapper = new ObjectMapper();
//        ObjectNode rootNode = objectMapper.createObjectNode();
//        rootNode.put("appid",appId);
//        rootNode.put("mchid",merchantId);
//        rootNode.put("description","早餐支付");
//        rootNode.put("out_trade_no",orderNum);
//        rootNode.put("notify_url", "https://wdd.natapp4.cc/yw/api/pay/wxAppPayNotify.do");
//        rootNode.putObject("amount").put("total",totalMoney.intValue()).put("currency","CNY");
//        rootNode.putObject("payer").put("openid", openId);
//        objectMapper.writeValue(bos, rootNode);
//
//        httpPost.setEntity(new StringEntity(bos.toString("UTF-8"), "UTF-8"));
//        CloseableHttpResponse response = httpClient.execute(httpPost);
//        String bodyAsString = EntityUtils.toString(response.getEntity());
//        JSONObject jsonObject = JSONObject.parseObject(bodyAsString);
//        if(jsonObject.containsKey("code")) {
//            System.out.println(jsonObject.getString("message"));
//            return null;
//        }
//        String prepay_id = jsonObject.getString("prepay_id");
//        JSONObject jsonObject1 = WxSignUtil.WxTuneUp(prepay_id, appId, merchantPrivateKey);
//        return jsonObject1;
//    }
//
//    public static JSONObject pay2(String orderNum, BigDecimal amount,String openId) throws Exception {
//        //获取金额单位为分
//        BigDecimal totalMoney = amount.multiply(new BigDecimal(100));
//        final CloseableHttpClient httpClient = getHttpClient();
//        HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi");
//        httpPost.addHeader("Accept", "application/json");
//        httpPost.addHeader("Content-type","application/json; charset=utf-8");
//        ByteArrayOutputStream bos = new ByteArrayOutputStream();
//        ObjectMapper objectMapper = new ObjectMapper();
//        ObjectNode rootNode = objectMapper.createObjectNode();
//        rootNode.put("appid",appId);
//        rootNode.put("mchid",merchantId);
//        rootNode.put("description","早餐支付");
//        rootNode.put("out_trade_no",orderNum);
//        rootNode.put("notify_url", "https://wdd.natapp4.cc/yw/api/pay/wxAppPayNotify2.do");
//        rootNode.putObject("amount").put("total",totalMoney).put("currency","CNY");
//        rootNode.putObject("payer").put("openid", openId);
//        objectMapper.writeValue(bos, rootNode);
//        httpPost.setEntity(new StringEntity(bos.toString("UTF-8"), "UTF-8"));
//        CloseableHttpResponse response = httpClient.execute(httpPost);
//        String bodyAsString = EntityUtils.toString(response.getEntity());
//        JSONObject jsonObject = JSONObject.parseObject(bodyAsString);
//        if(jsonObject.containsKey("code")) {
//            System.out.println(jsonObject.getString("message"));
//            return null;
//        }
//        String prepay_id = jsonObject.getString("prepay_id");
//        JSONObject jsonObject1 = WxSignUtil.WxTuneUp(prepay_id, appId, merchantPrivateKey);
//        return jsonObject1;
//    }



    public static void refund(String orderNum, BigDecimal totalAmount,BigDecimal amount,String openId,String reason) throws Exception {
        //获取金额单位为分
        BigDecimal totalMoney = totalAmount.multiply(new BigDecimal(100));
        BigDecimal refundMoney = amount.multiply(new BigDecimal(100));
        final CloseableHttpClient httpClient = getHttpClient();
        HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi");
        httpPost.addHeader("Accept", "application/json");
        httpPost.addHeader("Content-type","application/json; charset=utf-8");
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectMapper objectMapper = new ObjectMapper();
        ObjectNode rootNode = objectMapper.createObjectNode();
        rootNode.put("out_trade_no",orderNum);
        rootNode.put("out_refund_no",orderNum);
        rootNode.put("reason",reason);
        rootNode.put("notify_url", "https://wdd.natapp4.cc/yw/api/pay/wxAppPayNotify.do");
        rootNode.putObject("amount").put("refund",refundMoney).put("total",totalMoney).put("currency","CNY");
        objectMapper.writeValue(bos, rootNode);
        httpPost.setEntity(new StringEntity(bos.toString("UTF-8"), "UTF-8"));
        CloseableHttpResponse response = httpClient.execute(httpPost);
        String bodyAsString = EntityUtils.toString(response.getEntity());
        JSONObject jsonObject = JSONObject.parseObject(bodyAsString);
        String status = jsonObject.getString("status");
        if(status.equals("SUCCESS")){
            log.info("退款成功");
        }else if(status.equals("CLOSED")){
            log.info("退款关闭");
        }else if(status.equals("PROCESSING")){
            log.info("退款处理中");
        }else if(status.equals("ABNORMAL")){
            log.info("退款异常");
        }
    }

    /**
     * 获取平台证书  只要首次执行
     * @throws URISyntaxException
     * @throws IOException
     */
    public static void getptcert() throws URISyntaxException, IOException, NotFoundException, GeneralSecurityException, HttpCodeException {
        URIBuilder uriBuilder = new URIBuilder("https://api.mch.weixin.qq.com/v3/certificates");
        HttpGet httpGet = new HttpGet(uriBuilder.build());
        httpGet.addHeader("Accept", "application/json");
        CloseableHttpResponse response = getHttpClient().execute(httpGet);
        String bodyAsString = EntityUtils.toString(response.getEntity());
        System.out.println(bodyAsString);
        JSONObject resourceJsons = JSONObject.parseObject(bodyAsString);
        JSONArray jsonArray = JSONArray.parseArray(resourceJsons.getString("data"));
        JSONObject resourceJson2 = jsonArray.getJSONObject(0);
        JSONObject resourceJson = resourceJson2.getJSONObject("encrypt_certificate");
        String associated_data = resourceJson.getString("associated_data");
        String nonce = resourceJson.getString("nonce");
        String ciphertext = resourceJson.getString("ciphertext");
        //解密，如果这里报错，就一定是APIv3密钥错误
        AesUtil aesUtil = new AesUtil(apiV3Key.getBytes());
        String resourceData = aesUtil.decryptToString(associated_data.getBytes(), nonce.getBytes(), ciphertext);
        System.out.println("解密后=" + resourceData);
    }

//    @Resource
//    private ISysErrorLogService sysErrorLogService;
//
//    /**
//     * 交易账单
//     * @throws URISyntaxException
//     * @throws IOException
//     */
//    public static TradeBillDataResp getZdUrl(String date) throws MyException,URISyntaxException, GeneralSecurityException, IOException, NotFoundException, HttpCodeException {
//        //交易账单
//        URIBuilder   uriBuilder =   new URIBuilder("https://api.mch.weixin.qq.com/v3/bill/tradebill?bill_date="+date+"&bill_type=ALL");
//        HttpGet httpGet = new HttpGet(uriBuilder.build());
//        httpGet.addHeader("Accept", "application/json");
//        CloseableHttpResponse response = getHttpClient().execute(httpGet);
//        String bodyAsString = EntityUtils.toString(response.getEntity());
//        JSONObject jsonObject1 = JSONObject.parseObject(bodyAsString);
//        String code = jsonObject1.getString("code");
//        if(StringUtils.isNotBlank(code)){
//            throw new MyException(code+"__"+jsonObject1.getString("message"));
//        }
//        String download_url = jsonObject1.getString("download_url");
//        TradeBillDataResp zdUrlDowload = getZdUrlDowload(download_url);
//        return zdUrlDowload;
//    }
//
//
//    /**
//     * 分账账单
//     * @throws URISyntaxException
//     * @throws IOException
//     */
//    public static FzBillDataResp getZdUrlFz(String date) throws MyException, URISyntaxException, GeneralSecurityException, IOException, NotFoundException, HttpCodeException {
//        //分账账单
//        URIBuilder  uriBuilder =  new URIBuilder("https://api.mch.weixin.qq.com/v3/profitsharing/bills?bill_date="+date);
//        HttpGet httpGet = new HttpGet(uriBuilder.build());
//        httpGet.addHeader("Accept", "application/json");
//        CloseableHttpResponse response = getHttpClient().execute(httpGet);
//        String bodyAsString = EntityUtils.toString(response.getEntity());
//        System.out.println(bodyAsString);
//        JSONObject jsonObject1 = JSONObject.parseObject(bodyAsString);
//        //{"code":"NO_STATEMENT_EXIST","message":"账单文件不存在"}
//        String code = jsonObject1.getString("code");
//        if(StringUtils.isNotBlank(code)){
//            throw new MyException(code+"__"+jsonObject1.getString("message"));
//            // insertLog(req, e, "1");
//        }
//        String download_url = jsonObject1.getString("download_url");
//        FzBillDataResp zdUrlDowloadFz = getZdUrlDowloadFz(download_url);
//        return zdUrlDowloadFz;
//    }
//
//
//    /**
//     * 交易账单
//     * @param dowloadUrl
//     * @return
//     * @throws Exception
//     */
//    public static TradeBillDataResp getZdUrlDowload(String dowloadUrl) throws SignatureException, NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException {
//        HttpRequest get = HttpUtil.createGet(dowloadUrl);
//        HttpUrl parse = HttpUrl.parse(dowloadUrl);
//        get.header("Authorization", "WECHATPAY2-SHA256-RSA2048"+" "+SignUtils.getToken("GET",parse,""));
//        HttpResponse execute = get.execute();
//        InputStream inputStream = execute.bodyStream();
//        File file = FileUtil.writeFromStream(inputStream, FileUtil.newFile("D:/tradeBill"+DateUtils.getDate("yyyy-MM-dd")+System.currentTimeMillis()+".xlsx"));
//        //List<String> list = FileUtil.readLines(file, "utf-8");
//        TradeBillDataResp tradeBillDataResp = parseBody(execute.body());
//        return tradeBillDataResp;
//    }
//
//    /**
//     * 交易账单 分账账单
//     * @param dowloadUrl
//     * @return
//     * @throws Exception
//     */
//    public static FzBillDataResp getZdUrlDowloadFz(String dowloadUrl) throws SignatureException, NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException {
//        HttpRequest get = HttpUtil.createGet(dowloadUrl);
//        HttpUrl parse = HttpUrl.parse(dowloadUrl);
//        get.header("Authorization", "WECHATPAY2-SHA256-RSA2048"+" "+SignUtils.getToken("GET",parse,""));
//        HttpResponse execute = get.execute();
//        InputStream inputStream = execute.bodyStream();
//        File file = FileUtil.writeFromStream(inputStream, FileUtil.newFile("D:/zdBill"+DateUtils.getDate("yyyy-MM-dd")+System.currentTimeMillis()+".xlsx"));
//        //List<String> list = FileUtil.readLines(file, "utf-8");
//        FzBillDataResp fzBillDataResp = parseBodyFz(execute.body());
//        return fzBillDataResp;
//    }
//
//    private static TradeBillDataResp parseBody(String body) {
//        TradeBillDataResp tradeBillDataResp = null;
//        List<TradeBillLineResp> tradeBillLineRespList = new ArrayList<>();
//        try {
//            body = body.replace("`", "");
//            String[] billDataStrArray = body.split("\r\n");
//
//            if (billDataStrArray.length > 0) {
//                /* 解析行数据 */
//                for (int i = 1; i < billDataStrArray.length - 2; i++) {
//                    // 填充空格，防止数组越界
//                    String billData = billDataStrArray[i] + " ";
//                    String[] data = billData.split(",");
//                    TradeBillLineResp tradeBillLineResp = TradeBillLineResp.class.getDeclaredConstructor().newInstance();
//                    for (Field field : TradeBillLineResp.class.getDeclaredFields()) {
//                        SplitIndex splitIndex = field.getAnnotation(SplitIndex.class);
//                        if (splitIndex != null) {
//                            int index = splitIndex.value();
//                            setFieldValue(tradeBillLineResp, field, data[index]);
//                        }
//                    }
//                    tradeBillLineRespList.add(tradeBillLineResp);
//                }
//                /* 解析汇总数据*/
//                // 填充空格，防止数组越界
//                String totalData = billDataStrArray[billDataStrArray.length - 1] + " ";
//                String[] totalDataArray = totalData.split(",");
//                TradeBillTotalResp tradeBillTotalResp = TradeBillTotalResp.class.getDeclaredConstructor().newInstance();
//                for (Field field : TradeBillTotalResp.class.getDeclaredFields()) {
//                    SplitIndex splitIndex = field.getAnnotation(SplitIndex.class);
//                    if (splitIndex != null) {
//                        int index = splitIndex.value();
//                        setFieldValue(tradeBillTotalResp, field, totalDataArray[index]);
//                    }
//                }
//
//                tradeBillDataResp = TradeBillDataResp.builder()
//                    .tradeBillTotalResp(tradeBillTotalResp)
//                    .tradeBillLineRespList(tradeBillLineRespList)
//                    .build();
//            }
//            return tradeBillDataResp;
//        } catch (Exception e) {
//            throw new RuntimeException("解析交易账单文件响应数据异常：" + e);
//        }
//    }
//
//    private static FzBillDataResp parseBodyFz(String body) {
//        FzBillDataResp tradeBillDataResp = null;
//        List<FzBillLineResp> tradeBillLineRespList = new ArrayList<>();
//        try {
//            body = body.replace("`", "");
//            String[] billDataStrArray = body.split("\r\n");
//
//            if (billDataStrArray.length > 0) {
//                /* 解析行数据 */
//                for (int i = 1; i < billDataStrArray.length - 2; i++) {
//                    // 填充空格，防止数组越界
//                    String billData = billDataStrArray[i] + " ";
//                    String[] data = billData.split(",");
//                    FzBillLineResp tradeBillLineResp = FzBillLineResp.class.getDeclaredConstructor().newInstance();
//                    for (Field field : FzBillLineResp.class.getDeclaredFields()) {
//                        SplitIndex splitIndex = field.getAnnotation(SplitIndex.class);
//                        if (splitIndex != null) {
//                            int index = splitIndex.value();
//                            setFieldValue(tradeBillLineResp, field, data[index]);
//                        }
//                    }
//                    tradeBillLineRespList.add(tradeBillLineResp);
//                }
//
//                /* 解析汇总数据*/
//                // 填充空格，防止数组越界
//                String totalData = billDataStrArray[billDataStrArray.length - 1] + " ";
//                String[] totalDataArray = totalData.split(",");
//                FzBillTotalResp tradeBillTotalResp = FzBillTotalResp.class.getDeclaredConstructor().newInstance();
//                for (Field field : FzBillTotalResp.class.getDeclaredFields()) {
//                    SplitIndex splitIndex = field.getAnnotation(SplitIndex.class);
//                    if (splitIndex != null) {
//                        int index = splitIndex.value();
//                        setFieldValue(tradeBillTotalResp, field, totalDataArray[index]);
//                    }
//                }
//
//                tradeBillDataResp = FzBillDataResp.builder()
//                    .fzBillTotalResp(tradeBillTotalResp)
//                    .fzBillLineRespList(tradeBillLineRespList)
//                    .build();
//            }
//            return tradeBillDataResp;
//        } catch (Exception e) {
//            throw new RuntimeException("解析交易账单文件响应数据异常：" + e);
//        }
//    }
//
//    /**
//     * 使用反射设置对象的属性值。
//     *
//     * @param obj   要设置属性值的对象
//     * @param field 属性
//     * @param value 属性值
//     * @throws IllegalAccessException 如果没有足够的权限访问属性
//     */
//    public static void setFieldValue(Object obj, Field field, String value)
//        throws IllegalAccessException, IntrospectionException, InvocationTargetException, ParseException {
//
//        Class<?> aClass = obj.getClass();
//        PropertyDescriptor propertyDescriptor = new PropertyDescriptor(field.getName(), aClass);
//        Method method = propertyDescriptor.getWriteMethod();
//        String type = field.getGenericType()
//            .toString();
//        if (!org.springframework.util.StringUtils.hasText(value)) {
//            return;
//        }
//        value = value.trim();
//        switch (type) {
//            case "class java.util.Date":
//                method.invoke(obj, DateUtils.parseDate(value,"yyyy-MM-dd HH:mm:ss"));
//                break;
//            case "class java.lang.String":
//                method.invoke(obj, value);
//                break;
//            case "class java.lang.Integer":
//                method.invoke(obj, Double.valueOf(value)
//                    .intValue());
//                break;
//            case "class java.lang.Long":
//                method.invoke(obj, Double.valueOf(value)
//                    .longValue());
//                break;
//            case "class java.lang.Double":
//                method.invoke(obj, Double.valueOf(value));
//                break;
//            case "class java.lang.Float":
//                method.invoke(obj, Double.valueOf(value)
//                    .floatValue());
//                break;
//            case "class java.lang.Character":
//                method.invoke(obj, value.toCharArray()[0]);
//                break;
//            case "class java.math.BigDecimal":
//                method.invoke(obj, new BigDecimal(value).setScale(4, RoundingMode.HALF_UP));
//                break;
//            default:
//                method.invoke(obj, (Object) null);
//                break;
//        }
//    }
//

    /**
     * 敏感信息加密
     * @param message
     * @param
     * @return
     * @throws IllegalBlockSizeException
     * @throws IOException
     * @throws InvalidKeyException
     * @throws BadPaddingException
     */
    public static String rsaEncryptOAEP(String message) throws IllegalBlockSizeException, IOException, InvalidKeyException, BadPaddingException {
        if(StringUtils.isBlank(message)){
            return "";
        }
        try {
            Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding");
            X509Certificate x509Certificate = PemUtil.loadCertificate(new ClassPathResource("cert.pem").getInputStream());
            //cipher.init(Cipher.ENCRYPT_MODE, certificate.getPublicKey());
            cipher.init(Cipher.ENCRYPT_MODE, x509Certificate.getPublicKey());
            byte[] data = message.getBytes("utf-8");
            byte[] cipherdata = cipher.doFinal(data);
            return Base64.getEncoder().encodeToString(cipherdata);
        } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
            throw new RuntimeException("当前Java环境不支持RSA v1.5/OAEP", e);
        } catch (InvalidKeyException e) {
            throw new IllegalArgumentException("无效的证书", e);
        } catch (IllegalBlockSizeException | BadPaddingException e) {
            throw new IllegalBlockSizeException("加密原串的长度不能超过214字节");
        }
    }

    /**
     * 敏感信息解密
     * @param ciphertext
     * @param privateKey
     * @return
     * @throws BadPaddingException
     * @throws IOException
     */
    public static String rsaDecryptOAEP(String ciphertext, PrivateKey privateKey)
        throws BadPaddingException, IOException {
        try {
            Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding");
            cipher.init(Cipher.DECRYPT_MODE, privateKey);

            byte[] data = Base64.getDecoder().decode(ciphertext);
            return new String(cipher.doFinal(data), "utf-8");
        } catch (NoSuchPaddingException | NoSuchAlgorithmException e) {
            throw new RuntimeException("当前Java环境不支持RSA v1.5/OAEP", e);
        } catch (InvalidKeyException e) {
            throw new IllegalArgumentException("无效的私钥", e);
        } catch (BadPaddingException | IllegalBlockSizeException e) {
            throw new BadPaddingException("解密失败");
        }
    }

    /**
     * 上传图片到微信服务器
     * @param filePath
     * @return
     * @throws URISyntaxException
     * @throws IOException
     * @throws NotFoundException
     * @throws GeneralSecurityException
     * @throws HttpCodeException
     */
    public static String upload(String localdoman,String filePath) throws URISyntaxException, IOException, NotFoundException, GeneralSecurityException, HttpCodeException {
        if(localdoman.equals(filePath)){
            return "";
        }
        final CloseableHttpClient httpClient = WechatPay.getHttpClient();
        URI uri = new URI("https://api.mch.weixin.qq.com/v3/merchant/media/upload");
        File file = new File(filePath);
        String media_id = "";
        try (FileInputStream ins1 = new FileInputStream(file)) {
            String sha256 = DigestUtils.sha256Hex(ins1);
            try (InputStream ins2 = new FileInputStream(file)) {
                HttpPost request = new WechatPayUploadHttpPost.Builder(uri)
                    .withImage(file.getName(), sha256, ins2)
                    .build();
                CloseableHttpResponse response = httpClient.execute(request);
                String bodyAsString = EntityUtils.toString(response.getEntity());
                JSONObject jsonObject = JSONObject.parseObject(bodyAsString);
                if(jsonObject.containsKey("code")) {
                    System.out.println(jsonObject.getString("message"));
                    return "";
                }
                media_id = jsonObject.getString("media_id");
            }
        }
        return  media_id;
    }


    /**
     * 获取微信HttpClient
     * @return
     */
    public static CloseableHttpClient getHttpClient() throws HttpCodeException, GeneralSecurityException, IOException, NotFoundException {
        // 获取证书管理器实例
        CertificatesManager certificatesManager = CertificatesManager.getInstance();
        // 向证书管理器增加需要自动更新平台证书的商户信息
        certificatesManager.putMerchant(merchantId, new WechatPay2Credentials(merchantId,
            new PrivateKeySigner(merchantSerialNumber, merchantPrivateKey)), apiV3Key.getBytes(StandardCharsets.UTF_8));
        // ... 若有多个商户号，可继续调用putMerchant添加商户信息
        // 从证书管理器中获取verifier
        Verifier verifier = certificatesManager.getVerifier(merchantId);
        WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
            .withMerchant(merchantId, merchantSerialNumber, merchantPrivateKey)
            .withValidator(new WechatPay2Validator(verifier))
            .withWechatPay(wechatPayCertificates);
        // ... 接下来，你仍然可以通过builder设置各种参数，来配置你的HttpClient

        // 通过WechatPayHttpClientBuilder构造的HttpClient，会自动的处理签名和验签，并进行证书自动更新
        //WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
        //     .withMerchant(merchantId, merchantSerialNumber, merchantPrivateKey)
        //     .withWechatPay(wechatPayCertificates);
        return builder.build();
    }

}
